package top.idetect.client.modules.cloth.controller;


import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.Style;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;
import top.idetect.client.common.api.CommonPage;
import top.idetect.client.common.api.CommonResult;
import top.idetect.client.modules.cloth.model.Clothinfo;
import top.idetect.client.modules.cloth.model.DynamicConfig;
import top.idetect.client.modules.cloth.model.Flaw;
import top.idetect.client.modules.cloth.service.ClothinfoService;
import top.idetect.client.modules.cloth.service.DynamicConfigService;
import top.idetect.client.modules.cloth.service.FlawService;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static top.idetect.client.modules.cloth.service.impl.FlawServiceImpl.flawStatisticCache;
//import static top.idetect.client.schedule.ImgDataResizeTask.imgResizeFlag;
import static top.idetect.client.schedule.IpUpdateTask.ipList;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wjh
 * @since 2024-03-15
 */
@Slf4j
@RestController
@RequestMapping("/cloth/flaw")
public class FlawController {

    @Autowired
    private FlawService flawService;

    @Autowired
    private ClothinfoService clothinfoService;

    @Autowired
    private DynamicConfigService dynamicConfigService;


    @ApiOperation("疵点数据统计")
    @GetMapping("/statistic")
    @ResponseBody
    public CommonResult statistic(@RequestParam(value = "clothSerial" ,required = false) String clothSerial,
                                  @RequestParam(value = "reloadDataFlag" ,required = false, defaultValue = "false") Boolean reloadDataFlag) throws ExecutionException, InterruptedException {
        if(reloadDataFlag){
            flawStatisticCache.remove(clothSerial);
        }
        List<Map> statisticList = flawService.statistic(clothSerial);
        return CommonResult.success(statisticList);
    }




    @ApiOperation("疵点统计数据导出word")
    @GetMapping("/word")
    @ResponseBody
    public void word(@RequestParam(value = "clothSerial" ,required = false) String clothSerial) throws IOException, ExecutionException, InterruptedException {

        List<Map> statisticList = flawService.statistic(clothSerial);
        Clothinfo clothinfo = clothinfoService.getByClothSerial(clothSerial);
        DynamicConfig class_str_v1 = dynamicConfigService.getByConfigName("flaw_class_str_v2");

        XWPFTemplate templateV1 = getTemplateV1(statisticList, clothinfo, class_str_v1.getConfigValue().split(","));

        String desktopDir = System.getProperty("user.home") + File.separator + "Desktop";
        File targetPath = new File(desktopDir);
        if (!targetPath.exists()) {
            targetPath.mkdirs();
        }
        templateV1.writeAndClose(new FileOutputStream(desktopDir + File.separator + "缺陷卷统计报表.docx"));
    }


    public XWPFTemplate getTemplateV1(List<Map> statisticList, Clothinfo clothinfo,String[] class_str_v1) throws IOException {
        Map map1 = statisticList.get(0);
        Map map2 = statisticList.get(1);
        Map map3 = statisticList.get(2);
        Map map4 = statisticList.get(3);

        ClassPathResource templateClassPathResource = new ClassPathResource("static/templatev3.docx");
        InputStream templateClassPathResourceInputStream = templateClassPathResource.getInputStream();

        String dir = System.getProperty("user.dir");
        String imgPath = dir + File.separator + "src" + File.separator + "main"+ File.separator + "resources"+ File.separator + "static"+ File.separator + clothinfo.getClothSerial() +"_echartsImg.png";


        String[] arrRow1 = new String[class_str_v1.length+1];
        arrRow1[0] = "分区";
        for (int i = 0; i < class_str_v1.length; i++) {
            arrRow1[i+1] = class_str_v1[i];
        }
        RowRenderData row1 = Rows.of(arrRow1).center().create();

        String[] arrRow2 = new String[class_str_v1.length+1];
        arrRow2[0] = "通道一";
        for (int i = 0; i < class_str_v1.length; i++) {
            arrRow2[i+1] = map1.get(class_str_v1[i]).toString();
        }
        RowRenderData row2 = Rows.of(arrRow2).center().create();

        String[] arrRow3 = new String[class_str_v1.length+1];
        arrRow3[0] = "通道二";
        for (int i = 0; i < class_str_v1.length; i++) {
            arrRow3[i+1] = map2.get(class_str_v1[i]).toString();
        }
        RowRenderData row3 = Rows.of(arrRow3).center().create();

        String[] arrRow4 = new String[class_str_v1.length+1];
        arrRow4[0] = "通道三";
        for (int i = 0; i < class_str_v1.length; i++) {
            arrRow4[i+1] = map3.get(class_str_v1[i]).toString();
        }
        RowRenderData row4 = Rows.of(arrRow4).center().create();

        String[] arrRow5 = new String[class_str_v1.length+1];
        arrRow5[0] = "合计";
        for (int i = 0; i < class_str_v1.length; i++) {
            arrRow5[i+1] = map4.get(class_str_v1[i]).toString();
        }
        RowRenderData row5 = Rows.of(arrRow5).center().create();

        return XWPFTemplate.compile(templateClassPathResourceInputStream).render(
                new HashMap<String, Object>(){{
                    put("result", "合格");
                    put("rate", "100");
                    put("variety", "铜箔瑕疵检测1.0");
                    put("clothSerial", clothinfo.getClothSerial());
                    put("beginTime", clothinfo.getTimestamp().toString().replace("T", " "));
                    put("endTime", "2024-04-09 17:13:33");
                    put("clothLong", clothinfo.getClothLong());
                    put("clothWidth", clothinfo.getClothWidth() * 1000);
                    put("defectTotal", clothinfo.getTotalCounts());

                    if(clothinfo.getTotalCounts() == 0 || clothinfo.getClothLong() == 0 || clothinfo.getClothWidth() == 0){
                        put("periodicDefect", 0);
                    }else{
                        DecimalFormat df = new DecimalFormat("#.##");
                        put("periodicDefect", df.format(clothinfo.getTotalCounts()/(clothinfo.getClothLong() * clothinfo.getClothWidth())));
                    }
//                    put("barCode", clothinfo.getBarCode());
//                    put("clothWeight", clothinfo.getClothWeight());
                    put("groupteam", clothinfo.getGroupteam());
                    put("operator", clothinfo.getOperator());

                    put("tableData", Tables.of( row1, row2, row3, row4, row5).create());

                    put("echartsImgBar", Pictures.ofLocal(imgPath).size(620, 400).create());
                }});
    }

    //单元格合并
//        RowRenderData row0 = Rows.of("分区统计",null, "分    类",null, null, null, null, null).center().bgColor("4472C4").create();
//        RowRenderData row1 = Rows.of("分区", "分区相关", "划痕", "污损", "线状", "针孔", "其他", "合计").center().create();
//        RowRenderData row2 = Rows.of("0", null, null, null, null, null, null, null). center().create();
//        RowRenderData row3 = Rows.of("1", null, null, null, null, null, null, null).center().create();
//        RowRenderData row4 = Rows.of(null, "2", null, null, null, null, null, null).center().create();
//        RowRenderData row5 = Rows.of("2", null, null, null, null, null, null, null).center().create();
//        RowRenderData row6 = Rows.of(null, "1", null, null, null, null, null, null).center().create();
//        RowRenderData row7 = Rows.of("合计", null, map.get("划痕").toString(), map.get("污损").toString(), map.get("线状").toString(), map.get("针孔").toString(), map.get("其他").toString(), map.get("合计").toString()).center().create();
//        MergeCellRule rule = MergeCellRule.builder()
//                .map(MergeCellRule.Grid.of(0, 0), MergeCellRule.Grid.of(0, 1))
//                .map(MergeCellRule.Grid.of(0, 2), MergeCellRule.Grid.of(0, 7))
//                .map(MergeCellRule.Grid.of(3, 0), MergeCellRule.Grid.of(4, 0))
//                .map(MergeCellRule.Grid.of(5, 0), MergeCellRule.Grid.of(6, 0))
//                .map(MergeCellRule.Grid.of(7, 0), MergeCellRule.Grid.of(7, 1))
//                .build();


    @GetMapping("/downloadWord")
    public ResponseEntity<byte[]> downloadWord() throws IOException {
        // 读取Word文件
        String desktopDir = System.getProperty("user.home") + File.separator + "Desktop";
        byte[] data = Files.readAllBytes(new File(desktopDir + File.separator + "缺陷卷统计报表.docx").toPath());

        // 设置响应头部
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "your-word-file.docx");

        return ResponseEntity.ok()
                .headers(headers)
                .body(data);
    }



    @PostMapping("/echartsImgUpload")
    @ApiOperation("疵点统计报表截图上传")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                   @RequestParam("clothSerial") String clothSerial) throws FileNotFoundException {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return "文件为空，请选择文件进行上传";
        }

        String dir = System.getProperty("user.dir");
        log.info("dir:{}", dir);
        dir = dir + File.separator + "src" + File.separator + "main"+ File.separator + "resources"+ File.separator + "static";

        File targetPath = new File(dir);
        if (!targetPath.exists()) {
            targetPath.mkdirs();
        }

        try {
            // 获取资源目录的绝对路径
            File uploadDirectory = ResourceUtils.getFile(dir);
            // 创建文件对象
            File dest = new File(uploadDirectory, clothSerial+"_echartsImg.png");
            // 将文件保存到服务器
            file.transferTo(dest);
            return "文件上传成功，保存路径：" + dest.getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败：" + e.getMessage();
        }
    }


    @ApiOperation("测试")
    @GetMapping("/test")
    @ResponseBody
    public CommonResult test() {
        return CommonResult.success(System.currentTimeMillis()/1000);
    }

    @ApiOperation("分页查询疵点数据")
    @GetMapping("/page")
    @ResponseBody
    public CommonResult page(@RequestParam(value = "keyword" ,required = false) String keyword,
                             @RequestParam(value = "clothSerial" ,required = false) String clothSerial,
                             @RequestParam(value = "classStr" ,required = false) String classStr,
                             @RequestParam(value = "orderBy" ,required = false) String orderBy,
                             @RequestParam(value = "realLen" ,required = false) Double realLen,
                             @RequestParam(value = "realArea" ,required = false) Double realArea,
                             @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                             @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        Page<Flaw> page = flawService.page(pageSize, pageNum, keyword, clothSerial, classStr, orderBy, realLen, realArea);
        for(Flaw flaw : page.getRecords()){
            if(flaw.getTimestampNew() != null){
                Long timeLong = Long.parseLong(flaw.getTimestampNew().substring(2, 12));
                LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeLong * 1000), ZoneOffset.of("+8"));
                flaw.setTimestamp(localDateTime);
            }
        }
        return CommonResult.success(CommonPage.restPage(page));
    }


/*    @ApiOperation("列表查询疵点数据")
    @GetMapping("/list")
    @ResponseBody
    public CommonResult list(@RequestParam(value = "classStr" ,required = false) String classStr,
                             @RequestParam(value = "clothSerial" ,required = false) String clothSerial) {
        HashMap<String, Object> map = new HashMap<>();
        if(StrUtil.isNotEmpty(clothSerial)){
            map.put("cloth_serial", clothSerial);
        }
        List<Flaw> flaws = flawService.listByMap(map);
        return CommonResult.success(flaws);
    }*/



    @ApiOperation("分页查询不包含图片的疵点数据")
    @GetMapping("/pageNoImg")
    @ResponseBody
    public CommonResult pageNoImg(@RequestParam(value = "classStr" ,required = false) String classStr,
                                  @RequestParam(value = "clothSerial" ,required = false) String clothSerial,
                                  @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                                  @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        Page<Flaw> page = flawService.pageNoImg(pageSize, pageNum,  clothSerial,classStr);
        for(Flaw flaw : page.getRecords()){
            if(flaw.getTimestampNew() != null){
                Long timeLong = Long.parseLong(flaw.getTimestampNew().substring(2, 12));
                LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeLong * 1000), ZoneOffset.of("+8"));
                flaw.setTimestamp(localDateTime);
            }
        }
        return CommonResult.success(CommonPage.restPage(page));
    }

    @ApiOperation("列表查询不包含图片的疵点数据")
    @GetMapping("/listNoImg")
    @ResponseBody
    public CommonResult listNoImg(@RequestParam(value = "classStr" ,required = false) String classStr,
                                  @RequestParam(value = "clothSerial" ,required = false) String clothSerial) {
        List<Flaw> flaws = flawService.listNoImg(clothSerial,classStr);
        for(Flaw flaw : flaws){
            if(flaw.getTimestampNew() != null){
                Long timeLong = Long.parseLong(flaw.getTimestampNew().substring(2, 12));
                LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeLong*1000), ZoneOffset.of("+8"));
                flaw.setTimestamp(localDateTime);
            }
        }
        return CommonResult.success(flaws);
    }



    @ApiOperation("查询单个疵点数据")
    @GetMapping("/get")
    @ResponseBody
    public CommonResult get(@RequestParam(value = "id" ,required = false) Long id) {
        Flaw flaw = flawService.getById(id);
        if(flaw.getTimestampNew() != null){
            Long timeLong = Long.parseLong(flaw.getTimestampNew().substring(2, 12));
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeLong*1000), ZoneOffset.of("+8"));
            flaw.setTimestamp(localDateTime);
        }
        return CommonResult.success(flaw);
    }



    @ApiOperation("疵点数据excel导出")
    @GetMapping("/excel")
    public void excelExport(@RequestParam(value = "classStr" ,required = false) String classStr,
                                    @RequestParam(value = "clothSerial" ,required = false) String clothSerial,
                                    HttpServletResponse response) {
        List<Flaw> flaws = flawService.listExcel(clothSerial,classStr);
        //获取当前系统时间,避免多次运行文件名重复,数据被覆盖
        long time = System.currentTimeMillis();
        //格式化时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        String format = simpleDateFormat.format(time);
        //指定将文件写到哪里,即文件位置
//        String fileName = "D:\\test\\疵点数据_" + format + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = "疵点数据_" + format + ".xlsx";

        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);

        //excelType指定工作表类型     sheet页签名称
//        EasyExcel.write(fileName, Flaw.class)
//                .excelType(ExcelTypeEnum.XLS)
//                .sheet("疵点数据")
//                .doWrite(flaws);
        try {
            EasyExcel.write(response.getOutputStream())
                    .head(Flaw.class)
                    .excelType(ExcelTypeEnum.XLS)
                    .sheet("疵点数据")
                    .doWrite(flaws);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @ApiOperation("查询设备所在局域网可用ip")
    @GetMapping("/getIpList")
    @ResponseBody
    public CommonResult getIpList() {
        return CommonResult.success(ipList);
    }


//    @ApiOperation("图片Resize任务开关")
//    @GetMapping("/imgResizeSwitch")
//    @ResponseBody
//    public CommonResult imgResizeSwitch() {
//        if(imgResizeFlag){
//            imgResizeFlag = false;
//            log.info("图片Resize任务已关闭");
//        }else {
//            imgResizeFlag = true;
//            log.info("图片Resize任务已开启");
//        }
//        return CommonResult.success(imgResizeFlag);
//    }
}

